import { NextRequest, NextResponse } from "next/server"; import { z } from "zod"; import { and, eq } from "drizzle-orm"; import { db } from "@/db/client"; import { listingMedia } from "@/db/schema"; import { assertSameOrigin, requireUser } from "@/lib/auth/session"; import { getListingFull, assertOwner } from "@/lib/listings/service"; import { apiError, handle, parseBody } from "@/lib/api"; export const dynamic = "force-dynamic"; const Body = z.object({ order: z.array(z.string().uuid()).max(40).optional(), captions: z.record(z.string().uuid(), z.string().max(140)).optional() }); /** Confirme l'état des médias d'une annonce : ordre et légendes (les fichiers sont déjà traités à l'upload). */ export async function POST(req: NextRequest, { params }: { params: Promise<{ id: string }> }) { try { await assertSameOrigin(); const u = await requireUser(); const { id } = await params; const b = await parseBody(req, Body); const l = await getListingFull(id); if (!l) return apiError(404, "not_found", "Annonce introuvable"); assertOwner(l, u.id, u.roles); const d = db(); if (b.order) for (const [i, mid] of b.order.entries()) await d.update(listingMedia).set({ position: i }).where(and(eq(listingMedia.id, mid), eq(listingMedia.listingId, id))); if (b.captions) for (const [mid, alt] of Object.entries(b.captions)) await d.update(listingMedia).set({ altText: alt }).where(and(eq(listingMedia.id, mid), eq(listingMedia.listingId, id))); return NextResponse.json({ ok: true, media: (await getListingFull(id))!.media.map((m) => ({ id: m.id, position: m.position, altText: m.altText })) }); } catch (e) { return handle(e); } }